
#include "captchafetcherfactory.h"

#include <QDir>
#include <QPluginLoader>

#include "genericcaptchafetcher.h"
#include "paths.h"
#include "log.h"

namespace Wishmaster
{
	class CaptchaFetcherFactoryImpl
	{
	public:
		CaptchaFetcherFactoryImpl()
		{
			plugins.append(new GenericCaptchaFetcher());
		}

		~CaptchaFetcherFactoryImpl()
		{
			qDeleteAll(plugins);
		}

		bool loadPluginsFromDirectory(const QString& path)
		{
			bool found = false;
			log(llNormal, "Loading captchafetchers from directory: %s", qPrintable(path));
			QDir dir(path);
			foreach(const QString& filename, dir.entryList(QDir::Files))
			{
				log(llDebug, "Trying to load: %s", qPrintable(filename));
				QPluginLoader loader(dir.absoluteFilePath(filename));
				QObject* instance = loader.instance();
				if(instance)
				{
					CaptchaFetcher* fetcher = qobject_cast<CaptchaFetcher*>(instance);
					if(fetcher)
					{
						if(pluginLoaded(fetcher->id()))
						{
							continue;
						}
						found = true;
						log(llNormal, "Loading captchafetcher: %s", qPrintable(fetcher->id()));
						plugins.append(fetcher);
					}
					else
						log(llDebug, "!fetcher");
				}
				else
					log(llDebug, "!instance: %s", qPrintable(loader.errorString()));
			}
			return found;
		}

		bool pluginLoaded(const QString& id)
		{
			foreach(CaptchaFetcher* fetcher, plugins)
			{
				if(fetcher->id() == id)
					return true;
			}
			return false;
		}

		CaptchaFetcher* plugin(const QString& id)
		{
			foreach(CaptchaFetcher* fetcher, plugins)
			{
				if(fetcher->id() == id)
					return fetcher;
			}
			return 0;
		}

	private:
		QList<CaptchaFetcher*> plugins;
	};

	CaptchaFetcherFactory::CaptchaFetcherFactory()
	{
		impl = new CaptchaFetcherFactoryImpl();
	}

	CaptchaFetcherFactory::~CaptchaFetcherFactory()
	{
		delete impl;
	}

	CaptchaFetcher* CaptchaFetcherFactory::makeCaptchaFetcher(const QString& id, Wishmaster2::Network::RequestManager* requestManager, const QVariantMap& params)
	{
		CaptchaFetcher* fetcher = impl->plugin(id);
		if(!fetcher)
			return 0;
		return fetcher->clone(requestManager, params);
	}

	void CaptchaFetcherFactory::loadPlugins()
	{
		if(impl->loadPluginsFromDirectory("./plugins/captchafetchers") ||
				impl->loadPluginsFromDirectory("../plugins/captchafetchers")) // Try to find plugins from build directory first
			return;

		if(!impl->loadPluginsFromDirectory(DefaultPath::captchaFetcherPlugins()))
		{
			log(llError, "Unable to find captchafetchers plugins");
		}
	}
}

